using ObjectPool;
using System.Collections;
using UnityEditor;
using UnityEngine;
using static EColor;

public class Character : Singleton<Character>
{
    #region 外部字段
    private EventSystem eventSystem;
    private ObjectManager objectManager;
    private Rigidbody2D m_rigidbody;
    #endregion

    #region 内部字段
    [SerializeField]
    private float maxHorizontalSpeed;
    public float MaxHorizontalSpeed => maxHorizontalSpeed;
    [SerializeField]
    private float maxFallSpeed;
    public float MaxFallSpeed => maxFallSpeed;

    public int keyCount;                //收集到的钥匙数

    public const int MAXENERGY = 3;     //最大射击次数
    [SerializeField]
    private int _Energy;                //可用射击次数
    public int Energy             
    {
        get => _Energy;
        set
        {
            if (value > MAXENERGY)
                value = MAXENERGY;
            eventSystem.EnergyChange?.Invoke(value);
            _Energy = value;
        }
    }

    [HideInInspector]
    public bool b_wantJump;
    [HideInInspector]
    public bool b_wantDash;
    [HideInInspector]
    public Vector2 drct_aim;
    [HideInInspector]
    public float drct_move_input;       //输入的移动方向

    [Header("状态")]
    [SerializeField]
    private EColor _EColor;
    public EColor EColor
    {
        get => _EColor;
        set
        {
            if (value != Blue && value != Green)
                return;
            eventSystem.ColorChange.Invoke(value);
            _EColor = value;
        }
    }

    public float distanceToGround;
    [SerializeField] 
    private bool _Grounded;
    public bool Grounded
    {
        get => _Grounded;
        set
        {
            if(value && !b_isDashing)
            {
                Energy = 1;
            }
            if (value && !b_isDashing)
            {
                eventSystem.TouchGround?.Invoke();
            }
            _Grounded = value;
        }
    }

    [SerializeField] 
    private bool _InWindArea;
    public bool InWindArea
    {
        get =>_InWindArea;
        set
        {
            _InWindArea = value;
            if (value)
            {
                m_rigidbody.gravityScale = 0f;
            }
            else if(!b_isDashing)
                m_rigidbody.gravityScale = 1f;
        }
    }

    public bool b_isDashing;
    public bool b_died;

    /// <summary>
    /// 人物面朝的方向，返回0表示与上一帧保持一致
    /// </summary>
    public float Direction_Face => VX > 0.1f ? SgnX : drct_move_input;

    public bool Wriggling => VX > 2f && !b_isDashing;
    public Vector2 Velocity_LastFixedUpdate { get; private set; }
    public float VX { get; private set; }
    public float VY { get; private set; }
    public float SgnX { get; private set; }     //禁止将SgnX赋值为0
    public float SgnY { get; private set; }     //禁止将SgnY赋值为0
    #endregion

    #region 生命周期
    private void Start()
    {
        DontDestroyOnLoad(gameObject);

        m_rigidbody = GetComponent<Rigidbody2D>();
        eventSystem = Service.Get<EventSystem>();
        objectManager = Service.Get<ObjectManager>();

        MyReset();
        StartCoroutine(LatePhysicesCheck());
    }

    private void FixedUpdate()
    {
        PhysicsCheck();
    }

    public void PhysicsCheck()
    {
        VX = Mathf.Abs(m_rigidbody.velocity.x);
        VY = Mathf.Abs(m_rigidbody.velocity.y);
        SgnX = Mathf.Sign(m_rigidbody.velocity.x);
        SgnY = Mathf.Sign(m_rigidbody.velocity.y);
        if (VX < 0.1f)
        {
            if (drct_move_input != 0)
                SgnX = drct_move_input;
            else
                SgnX = 1;
        }
        if (VY < 0.1f)
            SgnY = -1;
    }

    public IEnumerator LatePhysicesCheck()
    {
        for(; ; )
        {
            yield return new WaitForFixedUpdate();
            Velocity_LastFixedUpdate = m_rigidbody.velocity;
        }
    }

    #endregion

    #region 响应方法
    private void MyReset()
    {
        EColor = Blue;
        b_wantJump = false;
        b_wantDash = false;
        keyCount = 0;
    }
    #endregion

    #region 其它方法

    public void Die()
    {
        if (b_died)
            return;

        Service.Get<AudioPlayer>().CreateAudio("AudioSource/fx_die");
        b_died = true;
        objectManager.Activate(EObject.DieEffect, transform.position);
        m_rigidbody.velocity = Vector2.zero;
        EColor = Blue;
        StartCoroutine(Die_());
    }

    private IEnumerator Die_()
    {
        yield return new WaitForSeconds(1f);
        eventSystem.PlayerDie?.Invoke();
    }

    public void Spawn(Vector3 position)
    {
        transform.position = position;
        b_died = false;
        Energy = 0;
        InWindArea = false;
    }
    #endregion

    #region 保存或撤销对部分角色参数的修改
    [Header("保存的部分角色参数")]
    [ContextMenuItem("保存角色参数（editormode和playmode均有效）", "Save")]
    [ContextMenuItem("读取之前保存的角色参数（editormode有效，playmode临时有效）", "Load")]
    [SerializeField]
    private CharacterData data;
    private void Save()
    {
        data.maxFallSpeed = maxFallSpeed;
        data.maxHorizontalSpeed = maxHorizontalSpeed;
        Debug.Log($"角色参数已保存在{AssetDatabase.GetAssetPath(data)}");
    }
    private void Load()
    {
        maxFallSpeed = data.maxFallSpeed;
        maxHorizontalSpeed = data.maxHorizontalSpeed;
        Debug.Log($"已从{AssetDatabase.GetAssetPath(data)}读取角色参数");
    }
    #endregion
}
